package org.hackystat.devcathlon.event;

import java.util.HashMap;
import java.util.Map;

import javax.xml.datatype.XMLGregorianCalendar;

import org.hackystat.devcathlon.match.Match;
import org.hackystat.devcathlon.team.Team;

/**
 * Provides a representation of the results of invoking an Event on a specific team at a specific
 * time in a specific match.  
 * @author Philip Johnson
 */
public class EventScore {
  /** The base score used to calculate points. */  
  private int baseScore = 0;
  /** An explanation for this score. */
  private String explanation = "No explanation for this score was provided.";
  /** The time at which this event was scored. */
  private XMLGregorianCalendar timestamp;
  /** The match when this event occurred. */
  private Match match;
  /** The team that this event score is associated with. */
  private Team team;
  /** A map of any bonus points obtained by a team for this event score. */
  private Map<String, Integer> bonusScore2points = new HashMap<String, Integer>();
  
  /**
   * Represents the results of invoking an Event on a Team during a Match.
   * @param timestamp The timestamp when the Event was scored. 
   * @param match The Match associated with this Event and score. 
   * @param team The Team who was scored. 
   */
  public EventScore(XMLGregorianCalendar timestamp, Match match, Team team) {
    this.timestamp = timestamp;
    this.match = match;
    this.team = team;
  }
  
  /**
   * Sets the baseScore to baseScore. 
   * @param baseScore The new baseScore. 
   */
  public void setBaseScore(int baseScore) {
    this.baseScore = baseScore;
  }
  
  /**
   * Sets the explanation string. 
   * @param explanation The new explanation string. 
   */
  public void setExplanation(String explanation) {
    this.explanation = explanation;
  }
  
  /**
   * Adds additional explanation.  Appends the passed string to the current explanation, separated
   * with a space.  
   * @param additionalExplanation The additional explanation. 
   */
  public void appendExplanation(String additionalExplanation) {
    this.explanation = this.explanation + " " + additionalExplanation;
  }
  
  /**
   * Adds a bonus score and its associated points to this EventScore instance. 
   * @param bonusScoreName The name of the bonus. 
   * @param bonusScoreValue The value of this bonus. 
   */
  public void addBonusScore(String bonusScoreName, int bonusScoreValue) {
    this.bonusScore2points.put(bonusScoreName, bonusScoreValue);
  }
  
  /**
   * Returns the map of bonus scores and their point values. 
   * @return The map of bonus scores. 
   */
  public Map<String, Integer> getBonusScoreMap() {
    return this.bonusScore2points;
  }
  
  /**
   * Returns the bonus score given the name, or 0 if the bonus score name is not present
   * in the map.
   * @param bonusScoreName The bonus score name. 
   * @return The score if present, or 0 if not present.
   */
  public int getBonusScore(String bonusScoreName) {
    return (this.bonusScore2points.containsKey(bonusScoreName)) ? 
        this.bonusScore2points.get(bonusScoreName) : 
          0;
  }
  
  /**
   * Returns true if this event score has bonus scores. 
   * @return True if there are bonuses to be had. 
   */
  public boolean hasBonusScores() {
    return !this.bonusScore2points.isEmpty();
  }
  
  /**
   * Returns the base score. 
   * @return The base score. 
   */
  public int getBaseScore() {
    return this.baseScore;
  }
  
  /**
   * Returns the explanation. 
   * @return The explanation. 
   */
  public String getExplanation() {
    return this.explanation;
  }
  
  /**
   * Returns the timestamp when this score was assessed. 
   * @return The timestamp.
   */
  public XMLGregorianCalendar getTimestamp() {
    return this.timestamp;
  }
  
  /**
   * Returns the Match associated with this score. 
   * @return The match.
   */
  public Match getMatch() {
    return this.match;
  }
  
  /**
   * Returns the team who got this score. 
   * @return The team. 
   */
  public Team getTeam() {
    return this.team;
  }
}



